#-- encoding: utf-8 --

import xml.dom.minidom


'''Parser xml document.Traverse the shader and material to find the connection between them. Change the connection
between the material and the shader and the value of the meterial's covset property. Add enough shader nodes and
their attributes.
Aurthor: ShiWeitao
Date: 2018-5-7
Raises:
    1.IndexError ：list index out of range(max_min=110)
'''

lst_file, lst_pd, lst_ai, lst_aov, lst_name= [], [], [], [], []
def part_lst_pd(shaders):

    for i in shaders:
        if 'utility' == i.getAttribute('shadertype'):
            coshader1 = i.getElementsByTagName('coshader')
            if coshader1:
                lst_file.append(i.getAttribute('name'))
            else:
                lst_pd.append(i.getAttribute('name'))
        else:
            lst_ai.append(i.getAttribute('name'))
            coshader1 = i.getElementsByTagName('coshader')
            for m in coshader1:
                lst_aov.append(m.getAttribute('aovset'))
    return lst_pd


lst_mid, lst_parent, lst1, lst2 = [], [], [], []

lst1, lst2, co = [], [], []
dic1 = {}
def contact_lst_pd_parent(shaders, lst_pd):

    for i in shaders:
        coshader2 = i.getElementsByTagName('coshader')
        for a in coshader2:
            for b in lst_pd:
                if a.getAttribute('shader') == b:
                    if dic1.has_key(i.getAttribute('name')):
                        pass
                    else:
                        dic1[i.getAttribute('name')] = b
                        lst1 = []
                        lst1.append(b)
                        lst1.append(i.getAttribute('name'))
                        lst_mid.append(i.getAttribute('name'))
                        lst2.append(lst1)
    return lst2


dic2 = {}

def rename_lst_pd(lst2):

    k = 0
    for a, i in enumerate(lst2):
        if dic2.has_key(i[0]):
            k += 1
            name = i[0] + str(k)
            dic2[i[0]] = i[1]
            i[0] = name
        else:
            dic2[i[0]] = i[1]
    return lst2


def contact_p2d_parent_parent(shaders, lst2):

    for i in shaders:
        coshader3 = i.getElementsByTagName('coshader')
        for a in coshader3:
            for b in lst2:
                if a.getAttribute('shader') == b[1]:
                    b.append(i.getAttribute('name'))
    return lst2


lst_fu_node, lst_node1, lst_node2, lst_node3 = [], [], [], []
def traversal_p2d(shaders, lst_pd):

    for i in range(len(lst_pd)):
        for n in shaders:
            if lst_pd[i] == n.getAttribute('name'):
                dic3 = {}
                dic3['name'] = n.getAttribute('name')
                dic3['shaderprogram'] = n.getAttribute('shaderprogram')
                dic3['shadertype'] = n.getAttribute('shadertype')
                lst_fu_node.append(dic3)
                coshader4 = n.getElementsByTagName('coshader')
                parameter1 = n.getElementsByTagName('parameter')
                for j in coshader4:
                    dic4 = {}
                    dic4['aovset'] = j.getAttribute('aovset')
                    dic4['name'] = j.getAttribute('name')
                    dic4['shader'] = j.getAttribute('shader')
                    lst_node1 = []
                    lst_node1.append(n.getAttribute('name'))
                    lst_node1.append('coshader')
                    lst_node1.append(dic4)
                    lst_node2.append(lst_node1)

                for k in parameter1:
                    dic5 = {}
                    dic5['name'] = k.getAttribute("name")
                    dic5['type'] = k.getAttribute('type')
                    dic5['value'] = k.getAttribute('value')
                    if k.hasAttribute('default'):
                        dic5['default'] = k.getAttribute('default')
                    lst_node1 = []
                    lst_node1.append(n.getAttribute('name'))
                    lst_node1.append('parameter')
                    lst_node1.append(dic5)
                    lst_node2.append(lst_node1)
    lst_node3.append(lst_fu_node)
    lst_node3.append(lst_node2)
    return lst_node3


def change_shader_aovset_for_ai(shaders, lst2):

    for g in range(len(lst2)):
        for i in shaders:
            if i.getAttribute('name') == lst2[g][2]:
                co = i.getElementsByTagName('coshader')
                for c in co:
                    if c.getAttribute('shader') == lst2[g][1]:

                        c.setAttribute('aovset', 'o_out')
                        c.setAttribute('shader', lst2[g][0])


def create_p2d_node(shaders, domtree, lst2, lst_pd,lst_fu_node):

    for h in range(len(lst2)):
        for a, pd in enumerate(lst_pd):
            if lst2[h][0] != pd and pd in lst2[h][0]:
                for s, sd in enumerate(shaders):
                    if s == 0:
                        shader_elem = domtree.createElement('shader')
                        shader_elem.setAttribute('name',lst2[h][0])
                        shader_elem.setAttribute('shaderprogram', lst_fu_node[a].get('shaderprogram'))
                        shader_elem.setAttribute('shadertype', lst_fu_node[a].get('shadertype'))
                        sd.parentNode.appendChild(shader_elem)


def set_old_for_p2d(domtree, lst2, lst_pd, lst_node2):

    shaders2 = domtree.getElementsByTagName('shader')
    for i in range(len(lst2)):
        for e in shaders2:
            for t in range(len(lst_pd)):
                if lst_pd[t] != lst2[i][0] and lst_pd[t] in lst2[i][0] and lst2[i][0] == e.getAttribute('name'):
                    for s, nd in enumerate(lst_node2):
                        if nd[0] in lst2[i][0]:
                            co_elem = domtree.createElement(nd[1])
                            lst_key, lst_value = [], []
                            lst_key = nd[2].keys()
                            lst_value = nd[2].values()
                            for v, value in enumerate(lst_value):
                                co_elem.setAttribute(lst_key[v], value)
                            e.appendChild(co_elem)


def set_new_for_p2d(domtree, lst2):

    shaders3 = domtree.getElementsByTagName('shader')
    for i in range(len(lst2)):
        for x in shaders3:
            if lst2[i][0] == x.getAttribute('name'):
                param_elem = domtree.createElement('coshader')
                param_elem.setAttribute('aovset', 'o_out')
                param_elem.setAttribute('name', 'i_passthrough')
                param_elem.setAttribute('shader', lst2[i][1])
                x.appendChild(param_elem)


def main(domtree):

    shaders = domtree.getElementsByTagName('shader')
    lst_pd = part_lst_pd(shaders)
    lst2 = contact_lst_pd_parent(shaders, lst_pd)
    lst2 = rename_lst_pd(lst2)
    lst2 = contact_p2d_parent_parent(shaders, lst2)
    lst_node3 = traversal_p2d(shaders, lst_pd)
    lst_fu_node = lst_node3[0]
    lst_node2 = lst_node3[1]
    change_shader_aovset_for_ai(shaders, lst2)
    create_p2d_node(shaders, domtree, lst2, lst_pd, lst_fu_node)
    set_old_for_p2d(domtree, lst2, lst_pd, lst_node2)
    set_new_for_p2d(domtree, lst2)
    f = open('/home/sunweiwu/test01.xml', 'w')
    domtree.writexml(f, addindent = ' ' , newl = '\n' ,encoding = 'utf-8')
    f.close()
    return domtree
